/**
 * @author denis.onishchenko@gmail.com
 */

package com.prapp.mediag;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;

import com.feeder.Text;

public final class ArticleActivity extends Activity {

    private static final int G_ROOT = -100;
    private static final int G_SHARE = -101;

    private static final int SHARE = -102;
    private static final int TWITTER = -103;
    private static final int FACEBOOK = -104;
    private static final int EMAIL = -105;
    private static final int IN_BROWSER = -106;
    private static final int MARK_READ = -107;
    private static final int OPTIONS = -108;
    private static final int SETTINGS = -109;
    private static final int HOME = -110;

    private static final int D_SETTINGS = -111;
    private static final int D_OPTIONS = -112;

    private PRApplication application;
    private Repository repository;

    private boolean finish;

    private Post post;
    private Long postId, previousPostId, nextPostId;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.article);

        Bundle extras = getIntent().getExtras();

        int tabIndex = extras.getInt(PRApplication.TAB_INDEX);
        long postId = extras.getLong(PRApplication.POST_ID);

        application = (PRApplication) getApplication();
        repository = application.getRepository(tabIndex);

        finish = false;

        Config.Tab tab = application.getTab(tabIndex);
        String title = tab.getName();
        if (title != null) {
            TextView titleTextView = (TextView) findViewById(R.id.tvTitle);
            titleTextView.setText(title);
        }

        ImageButton previousButton = (ImageButton) findViewById(R.id.bPrevious);
        ImageButton nextButton = (ImageButton) findViewById(R.id.bNext);
        ImageView favoritesImageView = (ImageView) findViewById(R.id.ivPostFavoriteIcon);

        previousButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                onShowArticle(previousPostId);
            }
        });
        nextButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                onShowArticle(nextPostId);
            }
        });
        favoritesImageView.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                boolean favorite = !post.getFavorite();

                post.setFavorite(favorite);
                repository.updateFavorite(post);

                ImageView favoriteImageView = (ImageView) findViewById(R.id.ivPostFavoriteIcon);
                int icon = favorite ? R.drawable.post_favorite : R.drawable.post_not_favorite;
                favoriteImageView.setImageResource(icon);
            }
        });

        onShowArticle(postId);
    }

    public void finish() {
        post = null;
        postId = previousPostId = nextPostId = null;

        super.finish();
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        SubMenu shareMenu = menu.addSubMenu(G_ROOT, SHARE, Menu.NONE, R.string.Share);
        shareMenu.setIcon(R.drawable.post_menu_share);

        shareMenu.add(G_SHARE, TWITTER, Menu.NONE, R.string.Twitter);
        shareMenu.add(G_SHARE, FACEBOOK, Menu.NONE, R.string.Facebook);
        shareMenu.add(G_SHARE, EMAIL, Menu.NONE, R.string.Email);


        MenuItem browserItem = menu.add(G_ROOT, IN_BROWSER, Menu.NONE, R.string.InBrowser);
        browserItem.setIcon(R.drawable.post_menu_in_browser);

        int markReadTitle = post.getRead() ? R.string.MarkUnread : R.string.MarkRead;
        int markReadIcon = post.getRead() ? R.drawable.post_menu_mark_unread : R.drawable.post_menu_mark_read;
        MenuItem markReadItem = menu.add(G_ROOT, MARK_READ, Menu.NONE, markReadTitle);
        markReadItem.setIcon(markReadIcon);

        MenuItem optionsItem = menu.add(G_ROOT, OPTIONS, Menu.NONE, R.string.Options);
        optionsItem.setIcon(R.drawable.post_menu_options);

        MenuItem settingsItem = menu.add(G_ROOT, SETTINGS, Menu.NONE, R.string.Settings);
        settingsItem.setIcon(R.drawable.post_menu_settings);

        MenuItem homeItem = menu.add(G_ROOT, HOME, Menu.NONE, R.string.Home);
        homeItem.setIcon(R.drawable.post_menu_home);

        return true;
    }

    public boolean onPrepareOptionsMenu(Menu menu) {
        int markReadTitle = post.getRead() ? R.string.MarkUnread : R.string.MarkRead;
        int markReadIcon = post.getRead() ? R.drawable.post_menu_mark_unread : R.drawable.post_menu_mark_read;

        MenuItem markReadItem = menu.findItem(MARK_READ);
        markReadItem.setTitle(markReadTitle);
        markReadItem.setIcon(markReadIcon);

        return super.onPrepareOptionsMenu(menu);
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        int groupId = item.getGroupId();
        int itemId = item.getItemId();

        switch (groupId) {
            case G_ROOT:
                switch (itemId) {
                    case IN_BROWSER:
                        onInBrowser();
                        return true;

                    case MARK_READ:
                        onMarkRead();
                        return true;

                    case OPTIONS:
                        showDialog(D_OPTIONS);
                        return true;

                    case SETTINGS:
                        showDialog(D_SETTINGS);
                        return true;

                    case HOME:
                        finish();
                        return true;
                }

            case G_SHARE:
                switch (itemId) {
                    case TWITTER:
                        onShareTwitter();
                        return true;
                    case FACEBOOK:
                        onShareFacebook();
                        return true;
                    case EMAIL:
                        onShareEmail();
                        return true;
                }
        }

        return super.onOptionsItemSelected(item);
    }

    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case D_OPTIONS:
                return onCreateOptionsDialog();
            case D_SETTINGS:
                return onCreateSettingsDialog();
        }

        return super.onCreateDialog(id);
    }

    protected void onPrepareDialog(int id, Dialog dialog) {
        switch (id) {
            case D_OPTIONS:
                onPrepareOptionsDialog(dialog);
                return;
            case D_SETTINGS:
                onPrepareSettingsDialog(dialog);
                return;
        }

        super.onPrepareDialog(id, dialog);
    }

    private void onShowArticle(Long postId) {
        try {
            application.trackPageView("/post");
        }
        catch (Throwable x) {
            Log.e(getClass().getName() + ".onShowArticle", "Can't track page view", x);
        }

        this.postId = postId;

        if (postId == null) {
            post = null;
            previousPostId = nextPostId = null;
            return;
        }

        post = repository.getPostById(postId);

        if (post == null)
            return;

        previousPostId = repository.getPreviousId(postId);
        nextPostId = repository.getNextId(postId);


        ImageButton previousButton = (ImageButton) findViewById(R.id.bPrevious);
        ImageButton nextButton = (ImageButton) findViewById(R.id.bNext);

        previousButton.setEnabled(previousPostId != null);
        nextButton.setEnabled(nextPostId != null);


        long categoryId = post.getCategoryId();
        Category category = repository.getCategoryById(categoryId);

        TextView categoryNameTextView = (TextView) findViewById(R.id.tvCategoryName);
        categoryNameTextView.setText(category.getName());

        TextView postDateTextView = (TextView) findViewById(R.id.tvPostDate);
        postDateTextView.setText(post.getDate().toLocaleString());

        TextView postTitleTextView = (TextView) findViewById(R.id.tvPostTitle);
        postTitleTextView.setText(post.getTitle());

        ImageView favoriteImageView = (ImageView) findViewById(R.id.ivPostFavoriteIcon);
        favoriteImageView.setImageResource(post.getFavorite() ? R.drawable.post_favorite : R.drawable.post_not_favorite);

        String description = repository.getDescription(postId);
        boolean showImages = application.getShowPostImages();
        WebSettings.TextSize textSize = application.getPostTextSize();

        WebView webView = (WebView) findViewById(R.id.wvContent);

        WebSettings settings = webView.getSettings();

        settings.setLoadsImagesAutomatically(showImages);
        settings.setTextSize(textSize);
        settings.setDatabaseEnabled(false);
        settings.setGeolocationEnabled(false);
        settings.setJavaScriptEnabled(false);
        settings.setLightTouchEnabled(false);
        settings.setPluginsEnabled(false);
        settings.setSupportZoom(false);

        webView.setBackgroundColor(Color.parseColor("#DFEFF2"));
        webView.loadDataWithBaseURL("", description, "text/html", "UTF-8", "");

        if (!post.getRead()) {
            post.setRead(true);
            repository.updateRead(post);
            boolean unread = application.getShowUnreadPosts();
            repository.synchronize(unread);
        }
    }

    private void onRefreshPostDescription() {
        String description = repository.getDescription(postId);
        boolean showImages = application.getShowPostImages();
        WebSettings.TextSize textSize = application.getPostTextSize();

        WebView postContentWebView = (WebView) findViewById(R.id.wvContent);

        WebSettings settings = postContentWebView.getSettings();

        settings.setLoadsImagesAutomatically(showImages);
        settings.setTextSize(textSize);
        settings.setDatabaseEnabled(false);
        settings.setGeolocationEnabled(false);
        settings.setJavaScriptEnabled(false);
        settings.setLightTouchEnabled(false);
        settings.setPluginsEnabled(false);
        settings.setSupportZoom(false);

        postContentWebView.setBackgroundColor(Color.parseColor("#DFEFF2"));
        postContentWebView.loadDataWithBaseURL("", description, "text/html", "UTF-8", "");
    }

    private void onShareTwitter() {
        try {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://twitter.com/home?status=" + Text.encode(post.getLink() + " " + post.getTitle()))));
        }
        catch (Throwable x) {
            Log.w(getClass().getName() + ".onShareTwitter", "Can't share with twitter", x);
        }
    }

    private void onShareFacebook() {
        try {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.facebook.com/sharer.php?u=" + Text.encode(post.getLink() + " " + post.getTitle()))));
        }
        catch (Throwable x) {
            Log.w(getClass().getName() + ".onShareFacebook", "Can't share with facebook", x);
        }
    }

    private void onShareEmail() {
        try {
            Intent intent = new Intent(Intent.ACTION_SEND);
            intent.setType("text/plain");
            intent.putExtra(Intent.EXTRA_SUBJECT, post.getTitle());
            intent.putExtra(Intent.EXTRA_TEXT, post.getTitle() + " - " + post.getLink());

            startActivity(Intent.createChooser(intent, getString(R.string.SendYourEmailIn)));
        }
        catch (Throwable x) {
            Log.w(getClass().getName() + ".onShareEmail", "Can't share with email", x);
        }
    }

    private void onInBrowser() {
        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(post.getLink())));
    }

    private void onMarkRead() {
        post.setRead(!post.getRead());
        repository.updateRead(post);

        boolean unread = application.getShowUnreadPosts();
        repository.synchronize(unread);
    }

    private void onDeleteAllImages() {
        repository.deleteAllImages();

        onRefreshPostDescription();
    }

    private void onDeleteOldPosts() {
        repository.deleteOldPosts();

        boolean unread = application.getShowUnreadPosts();
        repository.synchronize(unread);

        Post post = repository.getPostById(postId);
        finish = post == null;
    }

    private void onDeleteAllPosts() {
        repository.deleteAllPosts();

        finish = true;
    }

    private Dialog onCreateOptionsDialog() {
        LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.options, null);

        CheckBox showImagesCheckBox = (CheckBox) view.findViewById(R.id.cbShowImages);
        showImagesCheckBox.setChecked(application.getShowPostImages());
        showImagesCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                application.setShowPostImages(isChecked);
                onRefreshPostDescription();
            }
        });

        WebSettings.TextSize textSize = application.getPostTextSize();

        ImageView smallerImageView = (ImageView) view.findViewById(R.id.ivFontSmaller);
        smallerImageView.setEnabled(textSize != WebSettings.TextSize.SMALLEST);
        smallerImageView.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                WebSettings.TextSize textSize = application.getPostTextSize();

                v = (View) v.getParent();

                ImageView smallerImageView = (ImageView) v.findViewById(R.id.ivFontSmaller);
                ImageView biggerImageView = (ImageView) v.findViewById(R.id.ivFontBigger);

                switch (textSize) {
                    case SMALLEST:
                        return;
                    case SMALLER:
                        textSize = WebSettings.TextSize.SMALLEST;
                        break;
                    case NORMAL:
                        textSize = WebSettings.TextSize.SMALLER;
                        break;
                    case LARGER:
                        textSize = WebSettings.TextSize.NORMAL;
                        break;
                    case LARGEST:
                        textSize = WebSettings.TextSize.LARGER;
                        break;
                }

                smallerImageView.setEnabled(textSize != WebSettings.TextSize.SMALLEST);
                biggerImageView.setEnabled(textSize != WebSettings.TextSize.LARGEST);

                application.setPostTextSize(textSize);
                onRefreshPostDescription();
            }
        });

        ImageView biggerImageView = (ImageView) view.findViewById(R.id.ivFontBigger);
        biggerImageView.setEnabled(textSize != WebSettings.TextSize.LARGEST);
        biggerImageView.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                WebSettings.TextSize textSize = application.getPostTextSize();

                v = (View) v.getParent();

                ImageView smallerImageView = (ImageView) v.findViewById(R.id.ivFontSmaller);
                ImageView biggerImageView = (ImageView) v.findViewById(R.id.ivFontBigger);

                switch (textSize) {
                    case LARGEST:
                        return;
                    case LARGER:
                        textSize = WebSettings.TextSize.LARGEST;
                        break;
                    case NORMAL:
                        textSize = WebSettings.TextSize.LARGER;
                        break;
                    case SMALLER:
                        textSize = WebSettings.TextSize.NORMAL;
                        break;
                    case SMALLEST:
                        textSize = WebSettings.TextSize.SMALLER;
                        break;
                }

                smallerImageView.setEnabled(textSize != WebSettings.TextSize.SMALLEST);
                biggerImageView.setEnabled(textSize != WebSettings.TextSize.LARGEST);

                application.setPostTextSize(textSize);
                onRefreshPostDescription();
            }
        });

        return new AlertDialog.Builder(this)
                .setTitle(R.string.Settings)
                .setCancelable(false)
                .setView(view)
                .setOnKeyListener(new DialogInterface.OnKeyListener() {
                    public boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent event) {
                        int action = event.getAction();

                        if (action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
                            Dialog dialog = (Dialog) dialogInterface;
                            dialog.dismiss();

                            return true;
                        }

                        return false;
                    }
                })
                .create();
    }

    private Dialog onCreateSettingsDialog() {
        LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.settings, null);

        Spinner downloadImagesSpinner = (Spinner) view.findViewById(R.id.sDownloadImages);

        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.download_images, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        downloadImagesSpinner.setAdapter(adapter);

        Button deleteAllImagesButton = (Button) view.findViewById(R.id.bDeleteAllImages);
        deleteAllImagesButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                onDeleteAllImages();
            }
        });

        Button deleteOldPostsButton = (Button) view.findViewById(R.id.bDeleteOldPosts);
        deleteOldPostsButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                onDeleteOldPosts();
            }
        });

        Button deleteAllPostsButton = (Button) view.findViewById(R.id.bDeleteAllPosts);
        deleteAllPostsButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                onDeleteAllPosts();
            }
        });

        return new AlertDialog.Builder(this)
                .setTitle(R.string.Settings)
                .setCancelable(false)
                .setView(view)
                .setOnKeyListener(new DialogInterface.OnKeyListener() {
                    public boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent event) {
                        int action = event.getAction();

                        if (action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
                            Dialog dialog = (Dialog) dialogInterface;

                            CheckBox syncCheckBox = (CheckBox) dialog.findViewById(R.id.cbSync);
                            Spinner downloadImagesSpinner = (Spinner) dialog.findViewById(R.id.sDownloadImages);

                            application.setSyncItemsOnStart(syncCheckBox.isChecked());
                            int code = downloadImagesSpinner.getSelectedItemPosition();

                            application.setDownloadImages(code);

                            dialog.dismiss();

                            if (finish)
                                finish();

                            return true;
                        }

                        return false;
                    }
                })
                .create();
    }

    private void onPrepareOptionsDialog(Dialog dialog) {
        CheckBox showImagesCheckBox = (CheckBox) dialog.findViewById(R.id.cbShowImages);
        showImagesCheckBox.setChecked(application.getShowPostImages());

        WebSettings.TextSize textSize = application.getPostTextSize();

        ImageView smallerImageView = (ImageView) dialog.findViewById(R.id.ivFontSmaller);
        ImageView biggerImageView = (ImageView) dialog.findViewById(R.id.ivFontBigger);

        smallerImageView.setEnabled(textSize != WebSettings.TextSize.SMALLEST);
        biggerImageView.setEnabled(textSize != WebSettings.TextSize.LARGEST);
    }

    private void onPrepareSettingsDialog(Dialog dialog) {
        CheckBox syncCheckBox = (CheckBox) dialog.findViewById(R.id.cbSync);
        Spinner downloadImagesSpinner = (Spinner) dialog.findViewById(R.id.sDownloadImages);

        syncCheckBox.setChecked(application.getSyncItemsOnStart());
        downloadImagesSpinner.setSelection(application.getDownloadImages());
    }
}
